import { EventTouch, Vec2 } from "cc";
import { CardUI } from "../Entity/cardUI";
import { StateBlock } from "../utils/StateBlock/StateBlock";
import { GameUI, ICardDragData } from "../UI/gameUI";
import { CardData } from "../Data/CardData";
import EventProp from "../utils/EventSystem/EventProp";
import { ProbeEventList } from "../utils/EventSystem/EventList";
import { RuntimeCardData } from "../Data/BattleData";
import DataManager from "../utils/DataSystem/DataManager";
import BattleStateBlock from "./BattleStateBlock";

export default class CardStateBlock extends StateBlock{

    public static  async CreateFromRuntimeCard(jsonCardData : RuntimeCardData) : Promise<CardStateBlock>
    {
        let allData = await BattleStateBlock.AllCardData();
        let data = allData.find(item => item.id == jsonCardData.dataId);
        let card = new CardStateBlock(data);
        card.Name.Value = jsonCardData.name;
        card.Cost.Value = jsonCardData.cost;
        card.Attack.Value = jsonCardData.attack;
        card.MaxHealth.InitValue(jsonCardData.maxHealth);
        card.Health.Value = jsonCardData.health;
        return card;
    }

    protected InitState: typeof StateBlock = CardStateBlock_StateBase;

    public cardUI : CardUI;

    public gameUI : GameUI;

    //#region Data

    /**
     * 卡牌的原始数据
     */
    public CardData : CardData;

    public Name : EventProp<string> = new EventProp();

    /**
     * 卡牌法力值消耗
     */
    public Cost : EventProp<number> = new EventProp();
    /**
     * 卡牌攻击力
     */
    public Attack : EventProp<number> = new EventProp();
    /**
     * 卡牌当前生命值
     */
    public Health : EventProp<number> = new EventProp();

    /**
     * 卡牌当前最大生命值
     */
    public MaxHealth : EventProp<number> = new EventProp();
    //#endregion

    /**
     * 卡牌剩余攻击次数
     */
    public AttackCount : number = 0;

    /**
     * 这张卡是否寄了
     */
    public IsDead : boolean = false;

    /**
     * 当卡牌拖动中调用此方法
     */
    public OnCardDragging : Function = (event : EventTouch) => { console.log("OnCardDragging:No set func") };

    public OnCardDragEnd : Function = (dragInfo : ICardDragData) => { console.log("OnCardDragEnd:No set func") };


    //#region 事件
    /**
     * 卡牌即将攻击
     */
    public CardAttacking : ProbeEventList = new ProbeEventList();

    /**
     * 卡牌攻击
     */
    public CardAttacked : ProbeEventList = new ProbeEventList();

    /**
     * 卡牌死亡
     */
    public CardDead : ProbeEventList = new ProbeEventList();
    //#endregion

    constructor(data:CardData) {
        super();
        this.CardData = data;
    }

    /**
     * 重设攻击次数
     */
    public ResetAttackCount()
    {
        this.AttackCount = 1;
    }

    /**
     * 将卡牌重设为原始数据
     */
    public ResetCard()
    {
        this.Cost.Value = this.CardData.cost;
        this.MaxHealth.InitValue(this.CardData.health);
        this.Health.Value = this.CardData.health;
        this.Attack.Value = this.CardData.attack;

        this.Name.Value = this.CardData.name;

        this.IsDead = false;
        this.AttackCount = 0;
    }

    /**
     * 只是为了通知CardUI更新画面
     */
    public setSelf()
    {
        this.Cost.Value = this.Cost.Value;
        this.MaxHealth.InitValue(this.MaxHealth.Value);
        this.Health.Value = this.Health.Value;
        this.Attack.Value = this.Attack.Value;

        this.Name.Value = this.Name.Value;
    }

    public get IsHurt() : boolean {
        return this.Health.Value < this.MaxHealth.Value;
    }
    

}

export class CardStateBlock_StateBase extends StateBlock
{
    
    public get card() : CardStateBlock {
        return this.parent as CardStateBlock;
    }
    
}

/**
 * 卡牌手牌状态
 */
export class CardStateBlock_Hand extends CardStateBlock_StateBase
{
    public onEnter(): void {
        this.card.OnCardDragging = (event : EventTouch) => {
            // console.log(event);
            this.card.cardUI.SortOrder = 2;
            this.card.cardUI.node.setWorldPosition(event.getUILocation().x,event.getUILocation().y,0);
        };
        
        this.card.OnCardDragEnd = (drag:ICardDragData) => {
            this.card.cardUI.SortOrder = 0;
            if(!drag.isOutOfHand){
                this.card.cardUI.returnPos();
            }else{
                //
                if(!drag.gameUI.Battle.CanUseCard(this.card.CardData))
                {
                    this.card.cardUI.returnPos();
                }else{
                    drag.battle.cost.Value = drag.battle.cost.Value - this.card.CardData.cost;
                    drag.battle.TryUseCard(this.card);
                }
            }
        }
    }
}

/**
 * 卡牌友方状态
 */
export class CardStateBlock_Ally extends CardStateBlock_StateBase
{
    public onEnter(): void {
        this.card.OnCardDragging = (event : EventTouch)=>{

            if(this.card.AttackCount <= 0){
                return;
            }

            //  打开箭头
            if(!this.card.cardUI.Arrow.active){
                this.card.cardUI.Arrow.active = true;
            }
            //  让箭头跟随鼠标走
            //  旋转角度
            let sourcePos = this.card.cardUI.node.getWorldPosition();
            let targetPos = event.getUILocation();
            let vector = new Vec2(targetPos.x-sourcePos.x, targetPos.y-sourcePos.y);
            let angle = Math.atan2(vector.y,vector.x);
            //  旋转角度
            let r = angle * 180 / Math.PI - 90;
            //  距离
            let des = Math.sqrt(vector.x * vector.x + vector.y * vector.y);
            this.card.cardUI.setArrow(r,des);

        };

        this.card.OnCardDragEnd = (drag : ICardDragData) => {
            // 如果没有箭头，也就不能攻击
            if(!this.card.cardUI.Arrow.active){
                return;
            }
            //  关闭箭头
            this.card.cardUI.Arrow.active = false;
            //  如果没有目标，返回
            if(!drag.targetCard)
            {
                return;
            }

            if(drag.targetCard.currentStateKey != CardStateBlock_Enemy.name)
            {
                return;
            }

            drag.battle.TryAttack(this.card,drag.targetCard);
        };
    }
}

export class CardStateBlock_Enemy extends CardStateBlock_StateBase
{
    public onEnter(): void {
        this.card.OnCardDragging = (event : EventTouch) => {

        }
    }
}